;; Turn off the menus early on startup
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)

;;; Global configuration

;; Show column numbers on modeline
(column-number-mode 1)

;; I-search
(setq isearch-lazy-count t)
(setq lazy-count-prefix-format "(%s/%s) ")

;; yes-or-no-p -> y-or-n-p
(fset 'yes-or-no-p 'y-or-n-p)

;; File variables
(setq secondary-file-alist
      `((appearance-file ,(locate-user-emacs-file "appearance.el"))
        (vars-file ,(locate-user-emacs-file "custom-vars.el"))
        (auto-file ,(locate-user-emacs-file "auto.el"))
        (functions-file ,(locate-user-emacs-file "custom-functions.el"))
        (hooks-file ,(locate-user-emacs-file "hooks.el"))
        (expansions-file ,(locate-user-emacs-file "expansions.el"))
        (rc-file ,(locate-user-emacs-file "rc.el"))))

;; Put custom-set-variables and custom-set-faces in auto.el
(setq custom-file (cadr (assoc 'auto-file secondary-file-alist)))

;; Load files (first of all)
(dolist (f secondary-file-alist)
  (load (cadr f) 'noerror 'nomessage))

;; History length, auto-revert, backup directory, auto-save directory and their file name transforms.
(setq history-length 25
      global-auto-revert-non-file-buffers t
      tmp-dir (locate-user-emacs-file "tmp/")
      backup-directory-alist `((".*" . ,(locate-user-emacs-file (concat tmp-dir "emacs_backup/"))))
      auto-save-list-file-prefix (locate-user-emacs-file (concat tmp-dir "emacs_saves/"))
      auto-save-file-name-transforms `((".*" ,(locate-user-emacs-file (concat tmp-dir "emacs_saves/")) t))
      lock-file-name-transforms `((".*" ,(locate-user-emacs-file (concat tmp-dir "emacs_locks/")) t)))

;; Create auto-save list directory and lock file directory on startup if it does not exist
(rc/create-tmp-dirs tmp-dir)
;;(unless (file-exists-p (locate-user-emacs-file "tmp")) (make-directory (locate-user-emacs-file "tmp")))
;;(unless (file-exists-p auto-save-list-file-prefix) (make-directory auto-save-list-file-prefix))
;;(unless (file-exists-p (cadar lock-file-name-transforms)) (make-directory (cadar lock-file-name-transforms)))

;; Activate recentf
(recentf-mode 1)

;; General editing settings: tabs
(setq tab-always-indent 'complete
      tab-stop-list '(0 4 8))
(setq-default indent-tabs-mode nil)

;; Clipboard: also include the primary selection
(unless (or (eq system-type 'ms-dos) (eq system-type 'windows-nt) (eq system-type 'cygwin))
  (setq select-enable-clipboard t
        select-enable-primary t
        mouse-drag-copy-region nil))

;; cc-mode
(setq-default
 c-basic-offset 4
 c-default-style '((java-mode . "bsd")
                   (awk-mode . "awk")
                   (other . "bsd")))

;; VHDL
(setq-default
 vhdl-basic-offset 4)

;;Inferior Scheme program
(set-variable 'scheme-program-name "guile")

;; Auto-refresh buffers
(setq global-auto-revert-mode 1)
;; Auto-refresh dired
(setq global-auto-revert-non-file-buffers t)
(setq auto-revert-verbose nil)
;; One single buffer for dired
(when (boundp 'dired-kill-when-opening-new-dired-buffer)
  (setq dired-kill-when-opening-new-dired-buffer t))

;;; Package bootstrapping
(require 'package)
;;; Add MELPA and ELPA
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) ; ELPA is included by default
;;;; package-archives:
;;;;  (("gnu" . "https://elpa.gnu.org/packages/")
;;;;   ("nongnu" . "https://elpa.nongnu.org/nongnu/")
;;;;   ("melpa" . "https://melpa.org/packages/"))

(package-initialize)

;;; Packages
(rc/require 'paredit)
(rc/require 'smex)
;; ido
(require 'ido)
(ido-mode 1)
(ido-everywhere 1)
(setq ido-enable-flex-matching t)
(setq ido-use-filename-at-point 'guess)

;;; Hooks

;; Remove trailing whitespace
(add-hook 'before-save-hook
          'delete-trailing-whitespace)

;; Paredit
(add-hook 'emacs-startup-hook 'hooks/display-startup-time)
(add-hook 'lisp-mode-hook 'hooks/paredit-mode)
(add-hook 'emacs-lisp-mode-hook 'hooks/paredit-mode)
(add-hook 'common-lisp-mode-hook 'hooks/paredit-mode)
(add-hook 'scheme-mode-hook 'hooks/paredit-mode)
;; C-like languages: compilation and expansions
(add-hook 'c-mode-hook (lambda ()
                         ;;Compilation
                         (hooks/c-compilation custom/default-cc custom/default-cflags)
                         ;;Expansions
                         (expand-add-abbrevs c-mode-abbrev-table c-expand-list)
                         (abbrev-mode 1)))
(add-hook 'java-mode-hook (lambda ()
                            ;;Compilation
                            (hooks/java-compilation)
                            ;;Expansions
                            (expand-add-abbrevs java-mode-abbrev-table java-expand-list)
                            (abbrev-mode 1)))
;; Nroff
(add-hook 'nroff-mode-hook 'hooks/nroff-compilation)
;; Expand mode
(add-hook 'expand-expand-hook 'indent-according-to-mode)
(add-hook 'expand-jump-hook 'indent-according-to-mode)

;;; KEY bindings

;; Global bindings
(global-set-key (kbd "<C-return>") 'custom/newline-below)
(global-set-key (kbd "<C-S-return>") 'custom/newline-above)
(global-set-key (kbd "TAB") 'indent-for-tab-command)
(global-set-key (kbd "C-<tab>") 'expand-jump-to-next-slot)
(global-set-key (kbd "M-<tab>") 'expand-jump-to-previous-slot)
(global-set-key (kbd "M-x") 'smex)
(global-set-key (kbd "M-n") 'custom/move-lines-down)
(global-set-key (kbd "M-p") 'custom/move-lines-up)
(global-set-key (kbd "M-j") (lambda () (interactive) (join-line -1)))
(global-set-key (kbd "C-,") (lambda () (interactive) (duplicate-line) (next-line)))

;; Org-Mode global bindings
(global-set-key (kbd "C-c l") 'org-store-link)
(global-set-key (kbd "C-c a") 'org-agenda)
(global-set-key (kbd "C-c c") 'org-capture)

;; Windmove bindings
(global-set-key (kbd "C-c h") 'windmove-left)
(global-set-key (kbd "C-c j") 'windmove-down)
(global-set-key (kbd "C-c k") 'windmove-up)
(global-set-key (kbd "C-c l") 'windmove-right)

;; Minor mode bindings
(with-eval-after-load 'paredit (define-key paredit-mode-map (kbd "C-j") nil))    ; This way, you can evaluate and insert Elisp code in *scratch*.
